package org.yaac.server.egql.evaluator.function;

import org.yaac.server.egql.evaluator.EvaluationResult;
import org.yaac.server.egql.exception.EGQLException;
import org.yaac.server.egql.processor.ProcessData.ProcessDataRecord;
import org.yaac.shared.ErrorCode;

import com.google.appengine.api.datastore.GeoPt;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class GeoPtFunction extends Function {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void validate() throws EGQLException {
		FunctionUtil.ensureParamSize(ops, 2);
	}

	@Override
	public EvaluationResult evaluate(ProcessDataRecord record) {
		if (this.ops.isEmpty()) {
			return new EvaluationResult(null).withWarning(ErrorCode.W122);
		} else if (this.ops.size() == 2) {
			EvaluationResult r0 = this.ops.get(0).evaluate(record);
			EvaluationResult r1 = this.ops.get(1).evaluate(record);
			if (r0.getPayload() instanceof Number && r1.getPayload() instanceof Number) {
				float lat = ((Number)r0.getPayload()).floatValue();
				float lon = ((Number)r1.getPayload()).floatValue();
				
				try {
					return new EvaluationResult(new GeoPt(lat, lon), r0, r1);	
				} catch (IllegalArgumentException e) {
					// Longitude must be between -180 and 180 and Latitude must be between -90 and 90 (inclusive).
					return r1.withWarning(ErrorCode.W143);
				}
			} else {
				return r1.withWarning(ErrorCode.W123);
			}
		} else {
			return this.ops.get(0).evaluate(record).withWarning(ErrorCode.W122);
		}
	}
}
